package com.atguigu.yygh.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.cmn.client.DictFeignClient;
import com.atguigu.yygh.model.hosp.Hospital;
import com.atguigu.yygh.repository.HospitalRepository;
import com.atguigu.yygh.service.HospitalService;
import com.atguigu.yygh.vo.hosp.HospitalQueryVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @description: service调用repository操作mongondb
 * @author: 化一帆
 * @date: 2022/11/25 15:59
 * @version: v1.0
 */
@Service
public class HospitalServiceImpl implements HospitalService {
    @Autowired
    private HospitalRepository hospitalRepository;

    //注入远程调用服务的Feign的接口
    @Autowired
    private DictFeignClient dictFeignClient;

    /**
     * @description: 实现医院的上传
     * @author 化一帆
     * @date 2022/11/28 8:57
     */
    @Override
    public void save(Map<String, Object> paramMap) {
        //将map集合转换为对象[先将map转换为字符串，再将字符串转换为对象]
        String mapString = JSONObject.toJSONString(paramMap);
        Hospital hospital = JSONObject.parseObject(mapString, Hospital.class);

        //TODO 判断Mongodb的数据库中是否有数据存在，有的话就更新，没有的话执行添加的操作

        //1.判断是否存在数据
        String hoscode = hospital.getHoscode();
        Hospital hospitalExist = hospitalRepository.getHospitalByHoscode(hoscode);
        //2.如果存在，进行修改
        if (hospitalExist != null) {
            hospital.setStatus(hospitalExist.getStatus());
            hospital.setCreateTime(hospitalExist.getCreateTime());
            hospital.setUpdateTime(new Date());
            hospital.setIsDeleted(0);
            hospitalRepository.save(hospital);
        } else { //3.如果不存在，进行添加
            hospital.setStatus(0);
            hospital.setCreateTime(new Date());
            hospital.setUpdateTime(new Date());
            hospital.setIsDeleted(0);
            hospitalRepository.save(hospital);
        }


    }

    /**
     * @description: 根据医院的编号查询医院
     * @author 化一帆
     * @date 2022/11/28 8:57
     */
    @Override
    public Hospital getByHoscode(String hashcode) {
        Hospital hospital = hospitalRepository.getHospitalByHoscode(hashcode);

        return hospital;
    }

    /**
     * @description: 带条件的分页查询
     * @author 化一帆
     * @date 2022/11/29 14:10
     */
    @Override
    public Page<Hospital> selectHospitalPage(Integer page, Integer limit, HospitalQueryVo hospitalQueryVo) {
        //TODO 1.创建PageAble对象
        Pageable pageable= PageRequest.of(page-1, limit);

        //TODO 2.创建ExampleMatcher[条件匹配器对象]
        ExampleMatcher matcher=ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withIgnoreCase(true);
        //TODO 3.将封装条件的vo对象转换为普通对象
        Hospital hospital = new Hospital();
        BeanUtils.copyProperties(hospitalQueryVo, hospital);

        //TODO 4.创建Example实例，封装所有的查询条件
        Example<Hospital> example=Example.of(hospital,matcher);

        //TODO 5.调用Repository的findAll方法实现从Mongodb中数据查询
        Page<Hospital> pages = hospitalRepository.findAll(example, pageable);

        //TODO 6.以上这样查询只是查询Mongodb数据库中的数据，医院的等级信息还是value值，调用远程服务查询等级信息
       // List<Hospital> hospitalList = pages.getContent();//所有医院的信息的集合
            //查询获取list集合，遍历出每个医院对象，再将hostype的值封装进医院对象
            pages.getContent().stream().forEach(item ->{
                this.setHospitalHosType(item);
            });

            return pages;
    }

  /**
   * @description:  查询获取list集合，遍历进行医院等级的封装【跨服务，跨数据库，跨表】
   * @author 化一帆
   * @date 2022/11/29 21:45
   */
    private Hospital setHospitalHosType(Hospital hospital) {
        //根据dictCode和Value获取到了医院的等级名称【跨表，跨数据库，跨服务】
        //TODO [需要通过Mongodb中的hostype并没有明确医院等级，它代表的数字对应mysql中的value【MySQL中的等级的value不唯一】]
        String grade = dictFeignClient.getName("Hostype", hospital.getHostype());

        //将查询出来的医院的等级名称赋值到hospital对象的param属性中
        hospital.getParam().put("hostypeString", grade);

        //查询省provinceCode，省的value唯一
        String province = dictFeignClient.getName(hospital.getProvinceCode());

        //查询市
        String city = dictFeignClient.getName(hospital.getCityCode());

        //查询地区
        String district = dictFeignClient.getName(hospital.getDistrictCode());


        hospital.getParam().put("fullAddress", province+city+district+hospital.getAddress());
        return hospital;
    }


    /**
     * @description: 更新医院的上线状态
     * @author 化一帆
     * @date 2022/11/29 21:44
     */
    @Override
    public void updateHospStatus(String id, Integer status) {
        //1.根据id查询需要修改的值
        Hospital hospital = hospitalRepository.findById(id).get();

        //2.设置需要修改的值
        hospital.setStatus(status);
        hospital.setUpdateTime(new Date());

        //3.保存对象
        hospitalRepository.save(hospital);
    }

    /**
     * @description: 医院详情显示
     * @author 化一帆
     * @date 2022/11/30 8:54
     */
    @Override
    public Map<String,Object> getHospById(String id) {
        //既包含医院的基本信息，也包含医院的等级信息
        Hospital hospital1 = hospitalRepository.findById(id).get();
        Hospital hospital = this.setHospitalHosType(hospital1);

        HashMap<String, Object> result = new HashMap<>();

        result.put("hospital", hospital);
        //将预约信息放入map中
        result.put("bookingRule", hospital.getBookingRule());

        return result;
    }
    /**
     * @description: 获取医院的名称
     * @author 化一帆
     * @date 2022/12/1 15:01
     */
    @Override
    public String getHospName(String hoscode) {
        Hospital hospital = hospitalRepository.getHospitalByHoscode(hoscode);
        if(hospital!=null){
            return hospital.getHosname();
        }
        return null;
    }

    /**
     * @description:  根据医院的名称进行模糊查询
     * @author 化一帆
     * @date 2022/12/2 16:50
     */
    @Override
    public List<Hospital> findByHosname(String hosname) {
        return hospitalRepository.findHospitalByHosnameLike(hosname);
    }


    /**
     * @description:  根据医院的编号获取科室的预约挂号详情信息
     * @author 化一帆
     * @date 2022/12/2 19:01
     */
    @Override
    public Map<String, Object> item(String hoscode) {

        //创建封装返回结果的map集合
        HashMap<String, Object> result = new HashMap<>();

        //医院详情【methods：setHospitalHosType，methods：getByHoscode】
        Hospital hospital = this.setHospitalHosType(this.getByHoscode(hoscode));

        result.put("hospital", hospital);
        result.put("bookingRule", hospital.getBookingRule());

        return result;
    }

}
